// Copyright  2012 Petr TALLA. [petr.talla@gmail.com]
// This file is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This file is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY;  without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU Lesser General Public License for more details.
// [http://www.gnu.org/copyleft/lesser.html]
//=============================================================================

package tc.crase.sys;

import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import tc.common.registry.Obj;
import tc.common.registry.RegistrySys;
import tc.common.utility.Pair;

import tc.crase.db.Xattr;
import tc.crase.db.XattrGIT;
import tc.crase.db.XattrGRP;
import tc.crase.db.XattrLNK;
import tc.crase.db.XattrSTR;
import tc.crase.db.XattrTPE;
import tc.crase.db.Xdb;
import tc.crase.db.Xobject;
import tc.crase.meta.Type;

public class XobjectEx extends Xobject {
	private boolean selected = false;
	public ObjEx objex = new ObjEx();
	
	static public Vector<Xpair> attrsSelected = new Vector<Xpair>();
	
	static public boolean isAttrSeleced(Xattr attr) {
		for (int i = 0; i < attrsSelected.size(); i++) {
			if (attrsSelected.get(i).attr == attr) return true;
		}
		
		return false;
	}
	
	XobjectEx(String type, String name) {
		if ( name.isEmpty() == false) {
			attrAdd(new XattrSTR("name", name));
		}
		
		if ( type.isEmpty() == false) {
			attrAdd(new XattrTPE(type));
		}
	}
	
	public boolean getSelected() {
		return selected;
	}
	
	public void select(boolean value) {
		if (value == selected) return;
		
		selected = value;
		
		objex.objChanged();
		RegistrySys.registry.lock();
		RegistrySys.registry.unlock();
	}
	
	public String getType() {
		for (int i = 0; i < attrs.size(); i++) {
			XattrTPE tpe = attrs.get(i).getAsTPE();
			if (tpe == null) continue;
			return new String(tpe.id);
		}	
		
		return "";
	}
	
	@Override
	public void attrAdd(Xattr attr) {
		super.attrAdd(attr);
		objex.objChanged();
	}
	
	@Override
	public String getObjectName() {
		//XobjectEx xobjex = (XobjectEx)xobj;
		if (db == null) return super.getObjectName();
		XdbEx dbex = (XdbEx)db;
		Type type = dbex.metadata.types.get(getType());
		if (type == null) return "";
		return type.getObjectValue(this);
	}
	
	public void attrRemove(Xattr attr) {
		XattrLNK lnk = attr.getAsLNK();
			
		if (lnk != null) {
			XattrLNK lnkOpposite = lnk.getOpposite(); 
			XobjectEx parent = (XobjectEx)lnkOpposite.getParent(); 
			parent.attrs.remove(lnkOpposite);
			XobjectEx oppositeEx = (XobjectEx)(lnkOpposite.getParent());
			oppositeEx.objex.objChanged();
		}
		
		if (attr instanceof XattrGRP) {
			return;
		}
		
		if (attr instanceof XattrGIT) {
			XattrGIT gid = (XattrGIT)attr;
			XattrGRP grp = (XattrGRP)gid.getGId().searchAttr(getDb());
			grp.removeGID_(gid);
			XobjectEx ObjectGrp = (XobjectEx)grp.parent;
			ObjectGrp.objex.objChanged();
		}
		
		attrs.remove(attr);
		
		objex.objChanged();
		
		RegistrySys.registry.lock();
		RegistrySys.registry.unlock();
	}
	
	public void remove() {
		objex.objDeleted();
		
		//db.onRemove(this);
		dbOnRemove(db);
		
		//for (int i = 0; i < attrs.size(); i++) {
		for (Xattr attr : this) {
			XattrLNK lnk = attr.getAsLNK();
			if (lnk != null) {
				XattrLNK lnkOpposite = lnk.getOpposite(); 
				XobjectEx parent = (XobjectEx)lnkOpposite.getParent();
				parent.attrs.remove(lnkOpposite);
			}
			
			if (attr instanceof XattrGIT) {
				XattrGIT gitem = (XattrGIT)attr;
				XattrGRP grp = gitem.getGroup();
				grp.removeGID_(gitem);
				XobjectEx ObjectGrp = (XobjectEx)grp.parent;
				ObjectGrp.objex.objChanged();
			}
		}
		
		if (db!=null) db.removeObject(this);
		
		RegistrySys.registry.objects.remove(objex.obid);
		
		RegistrySys.registry.lock();
		RegistrySys.registry.unlock();
	}
	
	public boolean isType(String type) {
		for (int i = 0; i < attrs.size(); i++) {
			XattrTPE tpe = attrs.get(i).getAsTPE();
			if (tpe == null) continue;
			if (type.equals(tpe.id) == false ) continue;
			return true;
		}
		
		return false;
	}
	
	public String formatTypes() {
		String result = "";
		
		for (int i = 0; i < attrs.size(); i++) {
			Xattr attr = attrs.get(i);
			XattrTPE tpe = attr.getAsTPE();
			if (tpe == null) continue;
			if (result.isEmpty() == false) result += " "; 
			result += tpe.id;
		}
		
		if (result.isEmpty()) result = "NOTYPE";
		
		return result;
	}
	
	public XdbEx getDb() {
		return (XdbEx)db;
	}
	
	public ObjEx getObj() {
		return objex;
	}
	
	private XobjectEx getThis() {
		return this;
	}
	
	public class ObjEx extends Obj {
		public XobjectEx getObject() {
			return getThis();
		}
	}
}